/**
 * 210824：升级修改【three.js r120-r131】
 * 20220304:[require] to [import]...jordia
 */
import {Object3D,Vector3,Matrix4,Box3,Color,Vector2} from 'three';
import Texture from "./texture";
import Text from "../graphic/text";
import VirtualPlanes from "../graphic/mesh-points";
import Strips from '../graphic/strips';

const DEFAULT=[new Vector3(0,-1,0)];
const ZERO=new Vector3(0,0,0);

/**
 * 标签
 */
export default class Label extends Object3D{
    constructor(position=new Vector3(0,0,0),points=DEFAULT,values={}){
        super();
        this.position.copy(position);
        this.updateMatrixWorld();
        this.points=[];
        this.transformPoints(points);
        this.values=values;
        this.init();
    }

    /**
     * 设置相机控制器并添加/移除事件
     * @param camCtr
     */
    set camCtr(camCtr){
        if(this.cameraCtr){
            this.cameraCtr.eventCenter.removeEventListener('change',this._onCamChange);
            this.cameraCtr=null;
        }
        if(camCtr){
            this.cameraCtr=camCtr;
            this.cameraCtr.eventCenter.addEventListener('change',this._onCamChange);
        }
    }

    /**
     * 标签主体
     * @returns {null|Text}
     */
    get label(){
        return this.text;
    }

    /**
     * 连线
     * @returns {null|strips}
     */
    get line(){
        return this.link;
    }

    /**
     * 指向点
     * @returns {null|VirtualPlanes}
     */
    get point(){
        return this.pointer;
    }

    /**
     * 变化点集到局部坐标线
     * @param points
     * @param mat
     */
    transformPoints(points,mat=new Matrix4()){
        // mat.getInverse(this.matrixWorld);20210824
        mat.copy(this.matrixWorld).invert();
        for(let i=0;i<points.length;i++){
            let p=this.points[i]||new Vector3();
            p.copy(points[i]);
            p.applyMatrix4(mat);
            this.points[i]=p;
        }
    }
    init(){
        this.initVariable();
        this.initComponents();
        this.initEventHandle();
    }

    /**
     * 初始化事件句柄
     */
    initEventHandle(){
        this._onCamChange=()=>{};
    }

    /**
     * 初始化变量
     */
    initVariable(){
        this.text=null;
        this.pointer=null;
        this.link=null;
        this.tA0=[];
        this.cameraCtr=null;
        this.tV0=new Vector3();
        this.tV1=new Vector3();
        this.tV2=new Vector3();
        this.tV3=new Vector3();
        this.tV4=new Vector3();
        this.tV5=new Vector3();
        this.tV6=new Vector3();
        this.tB0=new Box3();
    }

    /**
     * 初始化组件
     */
    initComponents(){
        this.initText();
        this.initPointer();
        this.initLink();
    }

    /**
     * 初始化标签主体
     */
    initText(){
        this.text=new Text({
            text:this.values.text||'default',
            color:new Color(this.values.color||'#ffffff'),
            border:new Color(this.values.border||'#ffffff'),
            borderRadiusLeftBottom: 20,
            borderRadiusLeftTop: 20,
            borderRadiusRightBottom: 20,
            borderRadiusRightTop: 20,
            background:new Color(this.values.background||'#1e72a3'),
            lineWidth:0.06,
            fontSize:this.values.fontSize||16,
            vivid:2
        });
        this.add(this.text);
        this.text.center.copy(this.values.center||new Vector2(0.5,0.1));
    }

    /**
     * 初始化指向点
     */
    initPointer(){
        this.pointer=new VirtualPlanes(this.points,{
            map:Texture.longRound(64,64,1,{
                fill:this.values.border||'#ffffff',
            }),
            size:0.1
        });
        this.pointer.material.transparent=true;
        this.add(this.pointer);
    }

    /**
     * 初始化连线
     */
    initLink(){
        this.tA0.length=0;
        for(let point of this.points){
            this.tA0.push(ZERO.clone(),point);
        }
        this.link=new Strips(this.tA0,{
            width:0.02,
            color:new Color(this.values.border||'#ffffff'),
            opacity:this.values['linkOpacity']||0.4,
        });
        this.link.material.transparent=this.values['linkTransparent']===undefined?true:this.values['linkTransparent'];
        this.add(this.link);
    }
}